﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Services.Client;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using SilverlightClient.TransitODataServiceReference;

namespace SilverlightClient
{
    public partial class MainPage
    {
        private readonly TransitData _context;
        private readonly ObservableCollection<object> _observableCollection;
        private readonly CollectionViewSource _source;
        private string _serviceUrl = "http://transit.cloudapp.net/DevTransitODataService.svc/";

        public MainPage()
        {
            InitializeComponent();
            //   _serviceUrl = ConfigurationManager.AppSettings.Get("TransitODataServiceUrl");
            var uri = new Uri(_serviceUrl, UriKind.Absolute);
            _context = new TransitData(uri);
            _observableCollection = new ObservableCollection<object>();
            _source = (CollectionViewSource) LayoutRoot.Resources["_source"];
            _source.Source = _observableCollection;
            AgenciesButton.Click += OnExecuteButtonClick;
            StopsButton.Click += OnExecuteStopsButtonClick;
            ItinerariesButton.Click += OnExecuteItinerariesButtonClick;
            StopRosslynButton.Click += OnExecuteStopByNameButtonClick;
            ArriavalRosslynButton.Click += OnExecuteArriavalRosslynButtonClick;
        }

        private void OnExecuteButtonClick(object sender, RoutedEventArgs e)
        {
            AsyncCallback callback = delegate(IAsyncResult ar)
                                         {
                                             IEnumerable<Agency> itineraries = _context.EndExecute<Agency>(ar);
                                             if (itineraries != null)
                                                 Dispatcher.BeginInvoke(delegate
                                                 {
                                                                                foreach (Agency agency in itineraries)
                                                                                {

                                                                                    _observableCollection.Add(
                                                                                        string.Format("{0} ({1})",
                                                                                                      agency.Name,
                                                                                                      agency.State.Name));
                                                                                }
                                                                            });
                                             
                                         };


            var dataServiceQuery = (DataServiceQuery<Agency>)(from agency in _context.Agencies.Expand("State")
                                                               select agency);
            _context.BeginExecute<Agency>(dataServiceQuery.RequestUri, callback, null);

        }

        private void OnExecuteItinerariesButtonClick(object sender, RoutedEventArgs e)
        {
            //TransitODataService.svc/CalculateItineraryByStops?stop1Id='11868'&stop2Id='11882'&startTime=datetime'2009-12-26T01:23:38Z'
            string queryUri =
                string.Format(
                    "{0}CalculateItineraryByStops?stop1Id='{1}'&stop2Id='{2}'&startTime=datetime'{3}'&$expand=Legs",
                    _context.BaseUri, "11868", "11882", "2009-12-26T01:23:38Z");
            AsyncCallback callback = delegate(IAsyncResult ar)
                                         {
                                             IEnumerable<Itinerary> itineraries = _context.EndExecute<Itinerary>(ar);
                                             if (itineraries != null)
                                                 Dispatcher.BeginInvoke(delegate
                                                                            {
                                                                                foreach (
                                                                                    Itinerary itinerary in itineraries)
                                                                                {
                                                                                    _observableCollection.Add(
                                                                                        string.Format(
                                                                                            "Departure time:{0}, Arrival time:{1}, Transfers:{2}",
                                                                                            itinerary.StartTime,
                                                                                            itinerary.EndTime,
                                                                                            itinerary.TransferCount));
                                                                                }
                                                                            });
                                         };
            _context.BeginExecute<Itinerary>(new Uri(queryUri, UriKind.RelativeOrAbsolute), callback, null);
        }


        private void OnExecuteStopsButtonClick(object sender, RoutedEventArgs e)
        {
            AsyncCallback callback = delegate(IAsyncResult ar)
                                         {
                                             IEnumerable<GeoArea> geoAreas = _context.EndExecute<GeoArea>(ar);
                                             if (geoAreas != null)
                                             {
                                                 GeoArea area = geoAreas.FirstOrDefault();

                                                 Dispatcher.BeginInvoke(delegate
                                                                            {
                                                                                _observableCollection.Add(
                                                                                    string.Format(
                                                                                        "Area lat:{0},lon:{1},radius:{2} miles contains follow stops:",
                                                                                        area.Lat1, area.Lon1, area.Radius));

                                                                                foreach (Stop stop in area.Stops)
                                                                                {
                                                                                    _observableCollection.Add(string.Format("\t{0} ({1};{2})", stop.Name,stop.Lat,stop.Lon));
                                                                                }
                                                                            });
                                             }
                                         };
            var dataServiceQuery = (DataServiceQuery<GeoArea>)from geoArea in _context.GeoAreas.Expand("Stops")
                                                             where geoArea.ID == "38.996796|-76.904472|0.05"
                                                             select geoArea;
            _context.BeginExecute<GeoArea>(dataServiceQuery.RequestUri, callback, null);
        }

        private void OnExecuteArriavalRosslynButtonClick(object sender, RoutedEventArgs e)
        {
            AsyncCallback callback = delegate(IAsyncResult ar)
            {
                IEnumerable<GeoArea> geoAreas = _context.EndExecute<GeoArea>(ar);
                if (geoAreas != null)
                {
                    GeoArea area = geoAreas.FirstOrDefault();

                    Dispatcher.BeginInvoke(delegate
                    {
                        _observableCollection.Add("Near metro station Rosslyn:");

                        foreach (Stop stop in area.Stops)
                        {
                            _observableCollection.Add(string.Format("{3}:{0} ({1};{2})", stop.Name, stop.Lat, stop.Lon, stop.Type));
                            foreach (var arrival in stop.Arrivals)
                            {
                                _observableCollection.Add(string.Format("\t{0})", arrival.ArrivalSummary));
                            }

                        }
                    });
                }
            };
            var dataServiceQuery = (DataServiceQuery<GeoArea>)from geoArea in _context.GeoAreas.Expand("Stops/Arrivals")
                                                              where geoArea.ID == "38.8959790962|-77.0709086853|0.05"
                                                              select geoArea;
            _context.BeginExecute<GeoArea>(dataServiceQuery.RequestUri, callback, null);
        }

        
        private void OnExecuteStopByNameButtonClick(object sender, RoutedEventArgs e)
        {
            AsyncCallback callback = delegate(IAsyncResult ar)
            {
                IEnumerable<Stop> stops = _context.EndExecute<Stop>(ar);
                if (stops != null)
                {
                 

                    Dispatcher.BeginInvoke(delegate
                    {
                        _observableCollection.Add("All stops, which contains 'Rosslyn' in name:");

                        foreach (Stop stop in stops)
                        {
                            _observableCollection.Add(string.Format("\t{0} ({1};{2}) [{3}]", stop.Name, stop.Lat, stop.Lon,stop.StopId));
                        }
                    });
                }
            };
            var dataServiceQuery = (DataServiceQuery<Stop>)from stop in _context.Stops
                                                              where stop.Name.Contains("Rosslyn")
                                                              select stop;
            _context.BeginExecute<Stop>(dataServiceQuery.RequestUri, callback, null);
        }
    
    }
}